bitkeeper revision 1.1389.1.4 (427125bdwah0mehgnafVLP-gRLDM_w)
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 28 Apr 2005 18:04:45 +0000 (18:04 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 28 Apr 2005 18:04:45 +0000 (18:04 +0000)
Avoid field duplication between vcpu_guest_context and arch_exec_domain
structures. The latter now includes the former as a sub-field.
Signed-off-by: Keir Fraser <keir@xensource.com>
26 files changed:
linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c
linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/entry.S
tools/libxc/xc_linux_build.c
tools/libxc/xc_plan9_build.c
tools/libxc/xc_vmx_build.c
xen/arch/x86/dom0_ops.c
xen/arch/x86/domain.c
xen/arch/x86/domain_build.c
xen/arch/x86/i387.c
xen/arch/x86/mm.c
xen/arch/x86/traps.c
xen/arch/x86/vmx.c
xen/arch/x86/x86_32/asm-offsets.c
xen/arch/x86/x86_32/mm.c
xen/arch/x86/x86_32/seg_fixup.c
xen/arch/x86/x86_32/traps.c
xen/arch/x86/x86_64/asm-offsets.c
xen/arch/x86/x86_64/entry.S
xen/arch/x86/x86_64/mm.c
xen/arch/x86/x86_64/traps.c
xen/include/asm-x86/domain.h
xen/include/asm-x86/ldt.h
xen/include/asm-x86/processor.h
xen/include/asm-x86/x86_64/current.h
xen/include/public/arch-x86_32.h
xen/include/public/arch-x86_64.h

index 2dbf5477553f38fa2e1b5e69652813424b82d65b..ec1b3b9dead695aec97d5b6b94b583787539d867 100644 (file)
@@ -876,7 +876,7 @@ static int __init do_boot_cpu(int apicid)
        ctxt.user_regs.eflags = (1<<9) | (1<<2) | (idle->thread.io_pl<<12);
 
        /* FPU is set up to default initial state. */
-       memset(ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt));
+       memset(&ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt));
 
        /* Virtual IDT is empty at start-of-day. */
        for ( i = 0; i < 256; i++ )
@@ -903,8 +903,8 @@ static int __init do_boot_cpu(int apicid)
        }
 
        /* Ring 1 stack is the initial stack. */
-       ctxt.kernel_ss  = __KERNEL_DS;
-       ctxt.kernel_esp = idle->thread.esp;
+       ctxt.kernel_ss = __KERNEL_DS;
+       ctxt.kernel_sp = idle->thread.esp;
 
        /* Callback handlers. */
        ctxt.event_callback_cs     = __KERNEL_CS;
index 31bb6600d011462d8b5562c778ca53950ee05c4c..dbb4f588214a10f07a99c8149bbd970edb47aa46 100644 (file)
@@ -50,7 +50,7 @@
 
 
 EVENT_MASK      = (CS+4)
-ECF_IN_SYSCALL  = (1<<8)
+VGCF_IN_SYSCALL = (1<<8)
         
 /*
  * Copied from arch/xen/i386/kernel/entry.S
@@ -169,7 +169,7 @@ ECF_IN_SYSCALL  = (1<<8)
          *     struct switch_to_user {
          *        u64 rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
          *     } PACKED;
-         * #define ECF_IN_SYSCALL (1<<8) 
+         * #define VGCF_IN_SYSCALL (1<<8) 
          */
         .macro SWITCH_TO_USER flag
         movl $0,%gs:pda_kernel_mode     # change to user mode
@@ -275,7 +275,7 @@ sysret_check:
        jnz  sysret_careful 
         XEN_UNBLOCK_EVENTS(%rsi)                
        RESTORE_ARGS 0,8,0
-        SWITCH_TO_USER ECF_IN_SYSCALL
+        SWITCH_TO_USER VGCF_IN_SYSCALL
 
        /* Handle reschedules */
        /* edx: work, edi: workmask */  
index 1691415e63b8b1f5d036ddb6ceb0e23ea99b8659..abf427f87fef8137c5acba41dd23511fc3fb4f3c 100644 (file)
@@ -412,7 +412,7 @@ int xc_linux_build(int xc_handle,
     ctxt->user_regs.eflags = (1<<9) | (1<<2);
 
     /* FPU is set up to default initial state. */
-    memset(ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt));
+    memset(&ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt));
 
     /* Virtual IDT is empty at start-of-day. */
     for ( i = 0; i < 256; i++ )
@@ -432,8 +432,8 @@ int xc_linux_build(int xc_handle,
     ctxt->gdt_ents = 0;
 
     /* Ring 1 stack is the initial stack. */
-    ctxt->kernel_ss  = FLAT_KERNEL_DS;
-    ctxt->kernel_esp = vstartinfo_start + 2*PAGE_SIZE;
+    ctxt->kernel_ss = FLAT_KERNEL_DS;
+    ctxt->kernel_sp = vstartinfo_start + 2*PAGE_SIZE;
 
     /* No debugging. */
     memset(ctxt->debugreg, 0, sizeof(ctxt->debugreg));
index bb7356dc72c79978aa991efe72fbc15de817f47f..3260661acc968c1a68d4ee5b980cafb7c0217191 100644 (file)
@@ -498,7 +498,7 @@ xc_plan9_build(int xc_handle,
        ctxt->user_regs.eflags = (1 << 9) | (1 << 2);
 
        /* FPU is set up to default initial state. */
-       memset(ctxt->fpu_ctxt, 0, sizeof (ctxt->fpu_ctxt));
+       memset(&ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt));
 
        /* Virtual IDT is empty at start-of-day. */
        for (i = 0; i < 256; i++) {
@@ -519,7 +519,7 @@ xc_plan9_build(int xc_handle,
        /* Ring 1 stack is the initial stack. */
        /* put stack at top of second page */
        ctxt->kernel_ss = FLAT_KERNEL_DS;
-       ctxt->kernel_esp = ctxt->user_regs.esp;
+       ctxt->kernel_sp = ctxt->user_regs.esp;
 
        /* No debugging. */
        memset(ctxt->debugreg, 0, sizeof (ctxt->debugreg));
index 786f7a3cb69cd796dfaaea2648afd24ffbf78971..42b546fec646bd1af36dfe8b2768c111334a6509 100644 (file)
@@ -565,9 +565,9 @@ int xc_vmx_build(int xc_handle,
     if ( image != NULL )
         free(image);
 
-    ctxt->flags = ECF_VMX_GUEST;
+    ctxt->flags = VGCF_VMX_GUEST;
     /* FPU is set up to default initial state. */
-    memset(ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt));
+    memset(&ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt));
 
     /* Virtual IDT is empty at start-of-day. */
     for ( i = 0; i < 256; i++ )
@@ -588,8 +588,8 @@ int xc_vmx_build(int xc_handle,
 
     /* Ring 1 stack is the initial stack. */
 /*
-    ctxt->kernel_ss  = FLAT_KERNEL_DS;
-    ctxt->kernel_esp = vstartinfo_start;
+    ctxt->kernel_ss = FLAT_KERNEL_DS;
+    ctxt->kernel_sp = vstartinfo_start;
 */
     /* No debugging. */
     memset(ctxt->debugreg, 0, sizeof(ctxt->debugreg));
index a59b118d225e179779f0feeb71e75d0fc143e2d6..722317b6980793b2141911716aedc26c7b87dbdd 100644 (file)
@@ -383,10 +383,8 @@ void arch_getdomaininfo_ctxt(
 #endif
 #endif
 
-    c->flags = 0;
-    memcpy(&c->user_regs, 
-           &ed->arch.user_regs,
-           sizeof(ed->arch.user_regs));
+    memcpy(c, &ed->arch.guest_context, sizeof(*c));
+
     /* IOPL privileges are virtualised -- merge back into returned eflags. */
     BUG_ON((c->user_regs.eflags & EF_IOPL) != 0);
     c->user_regs.eflags |= ed->arch.iopl << 12;
@@ -398,30 +396,22 @@ void arch_getdomaininfo_ctxt(
 #endif
 #endif
 
+    c->flags = 0;
     if ( test_bit(EDF_DONEFPUINIT, &ed->ed_flags) )
-        c->flags |= ECF_I387_VALID;
-    if ( KERNEL_MODE(ed, &ed->arch.user_regs) )
-        c->flags |= ECF_IN_KERNEL;
+        c->flags |= VGCF_I387_VALID;
+    if ( KERNEL_MODE(ed, &ed->arch.guest_context.user_regs) )
+        c->flags |= VGCF_IN_KERNEL;
 #ifdef CONFIG_VMX
     if (VMX_DOMAIN(ed))
-        c->flags |= ECF_VMX_GUEST;
+        c->flags |= VGCF_VMX_GUEST;
 #endif
-    memcpy(&c->fpu_ctxt,
-           &ed->arch.i387,
-           sizeof(ed->arch.i387));
-    memcpy(&c->trap_ctxt,
-           ed->arch.traps,
-           sizeof(ed->arch.traps));
+
 #ifdef ARCH_HAS_FAST_TRAP
     if ( (ed->arch.fast_trap_desc.a == 0) &&
          (ed->arch.fast_trap_desc.b == 0) )
         c->fast_trap_idx = 0;
-    else
-        c->fast_trap_idx = 
-            ed->arch.fast_trap_idx;
 #endif
-    c->ldt_base = ed->arch.ldt_base;
-    c->ldt_ents = ed->arch.ldt_ents;
+
     c->gdt_ents = 0;
     if ( GET_GDT_ADDRESS(ed) == GDT_VIRT_START(ed) )
     {
@@ -430,22 +420,8 @@ void arch_getdomaininfo_ctxt(
                 l1e_get_pfn(ed->arch.perdomain_ptes[i]);
         c->gdt_ents = GET_GDT_ENTRIES(ed);
     }
-    c->kernel_ss  = ed->arch.kernel_ss;
-    c->kernel_esp = ed->arch.kernel_sp;
-    c->pt_base   = 
-        pagetable_val(ed->arch.guest_table);
-    memcpy(c->debugreg, 
-           ed->arch.debugreg, 
-           sizeof(ed->arch.debugreg));
-#if defined(__i386__)
-    c->event_callback_cs     = ed->arch.event_selector;
-    c->event_callback_eip    = ed->arch.event_address;
-    c->failsafe_callback_cs  = ed->arch.failsafe_selector;
-    c->failsafe_callback_eip = ed->arch.failsafe_address;
-#elif defined(__x86_64__)
-    c->event_callback_eip    = ed->arch.event_address;
-    c->failsafe_callback_eip = ed->arch.failsafe_address;
-    c->syscall_callback_eip  = ed->arch.syscall_address;
-#endif
+
+    c->pt_base = pagetable_val(ed->arch.guest_table);
+
     c->vm_assist = ed->domain->vm_assist;
 }
index 9a47fcaac8c3baf6af1bb8e49b88a528c94edd89..322b200a3a735a7d0556238528631ef72a22d97a 100644 (file)
@@ -385,65 +385,42 @@ int arch_set_info_guest(
      * #GP. If DS, ES, FS, GS are DPL 0 then they'll be cleared automatically.
      * If SS RPL or DPL differs from CS RPL then we'll #GP.
      */
-    if (!(c->flags & ECF_VMX_GUEST)) 
+    if ( !(c->flags & VGCF_VMX_GUEST) )
+    {
         if ( ((c->user_regs.cs & 3) == 0) ||
              ((c->user_regs.ss & 3) == 0) )
                 return -EINVAL;
+    }
 
     clear_bit(EDF_DONEFPUINIT, &ed->ed_flags);
-    if ( c->flags & ECF_I387_VALID )
+    if ( c->flags & VGCF_I387_VALID )
         set_bit(EDF_DONEFPUINIT, &ed->ed_flags);
 
     ed->arch.flags &= ~TF_kernel_mode;
-    if ( c->flags & ECF_IN_KERNEL )
+    if ( c->flags & VGCF_IN_KERNEL )
         ed->arch.flags |= TF_kernel_mode;
 
-    memcpy(&ed->arch.user_regs,
-           &c->user_regs,
-           sizeof(ed->arch.user_regs));
-
-    memcpy(&ed->arch.i387,
-           &c->fpu_ctxt,
-           sizeof(ed->arch.i387));
+    memcpy(&ed->arch.guest_context, c, sizeof(*c));
 
     /* IOPL privileges are virtualised. */
-    ed->arch.iopl = (ed->arch.user_regs.eflags >> 12) & 3;
-    ed->arch.user_regs.eflags &= ~EF_IOPL;
+    ed->arch.iopl = (ed->arch.guest_context.user_regs.eflags >> 12) & 3;
+    ed->arch.guest_context.user_regs.eflags &= ~EF_IOPL;
 
     /* Clear IOPL for unprivileged domains. */
-    if (!IS_PRIV(d))
-        ed->arch.user_regs.eflags &= 0xffffcfff;
+    if ( !IS_PRIV(d) )
+        ed->arch.guest_context.user_regs.eflags &= 0xffffcfff;
 
-    if (test_bit(EDF_DONEINIT, &ed->ed_flags))
+    if ( test_bit(EDF_DONEINIT, &ed->ed_flags) )
         return 0;
 
-    memcpy(ed->arch.traps,
-           &c->trap_ctxt,
-           sizeof(ed->arch.traps));
-
     if ( (rc = (int)set_fast_trap(ed, c->fast_trap_idx)) != 0 )
         return rc;
 
-    ed->arch.ldt_base = c->ldt_base;
-    ed->arch.ldt_ents = c->ldt_ents;
-
-    ed->arch.kernel_ss = c->kernel_ss;
-    ed->arch.kernel_sp = c->kernel_esp;
-
+    memset(ed->arch.guest_context.debugreg, 0,
+           sizeof(ed->arch.guest_context.debugreg));
     for ( i = 0; i < 8; i++ )
         (void)set_debugreg(ed, i, c->debugreg[i]);
 
-#if defined(__i386__)
-    ed->arch.event_selector    = c->event_callback_cs;
-    ed->arch.event_address     = c->event_callback_eip;
-    ed->arch.failsafe_selector = c->failsafe_callback_cs;
-    ed->arch.failsafe_address  = c->failsafe_callback_eip;
-#elif defined(__x86_64__)
-    ed->arch.event_address     = c->event_callback_eip;
-    ed->arch.failsafe_address  = c->failsafe_callback_eip;
-    ed->arch.syscall_address   = c->syscall_callback_eip;
-#endif
-
     if ( ed->eid == 0 )
         d->vm_assist = c->vm_assist;
 
@@ -475,7 +452,7 @@ int arch_set_info_guest(
     }
 
 #ifdef CONFIG_VMX
-    if ( c->flags & ECF_VMX_GUEST )
+    if ( c->flags & VGCF_VMX_GUEST )
     {
         int error;
 
@@ -507,7 +484,7 @@ void new_thread(struct exec_domain *d,
                 unsigned long start_stack,
                 unsigned long start_info)
 {
-    struct cpu_user_regs *regs = &d->arch.user_regs;
+    struct cpu_user_regs *regs = &d->arch.guest_context.user_regs;
 
     /*
      * Initial register values:
@@ -557,63 +534,63 @@ void toggle_guest_mode(struct exec_domain *ed)
 
 static void load_segments(struct exec_domain *p, struct exec_domain *n)
 {
+    struct vcpu_guest_context *pctxt = &p->arch.guest_context;
+    struct vcpu_guest_context *nctxt = &n->arch.guest_context;
     int all_segs_okay = 1;
 
     /* Either selector != 0 ==> reload. */
-    if ( unlikely(p->arch.user_regs.ds |
-                  n->arch.user_regs.ds) )
-        all_segs_okay &= loadsegment(ds, n->arch.user_regs.ds);
+    if ( unlikely(pctxt->user_regs.ds | nctxt->user_regs.ds) )
+        all_segs_okay &= loadsegment(ds, nctxt->user_regs.ds);
 
     /* Either selector != 0 ==> reload. */
-    if ( unlikely(p->arch.user_regs.es |
-                  n->arch.user_regs.es) )
-        all_segs_okay &= loadsegment(es, n->arch.user_regs.es);
+    if ( unlikely(pctxt->user_regs.es | nctxt->user_regs.es) )
+        all_segs_okay &= loadsegment(es, nctxt->user_regs.es);
 
     /*
      * Either selector != 0 ==> reload.
      * Also reload to reset FS_BASE if it was non-zero.
      */
-    if ( unlikely(p->arch.user_regs.fs |
-                  p->arch.user_regs.fs_base |
-                  n->arch.user_regs.fs) )
+    if ( unlikely(pctxt->user_regs.fs |
+                  pctxt->fs_base |
+                  nctxt->user_regs.fs) )
     {
-        all_segs_okay &= loadsegment(fs, n->arch.user_regs.fs);
-        if ( p->arch.user_regs.fs ) /* != 0 selector kills fs_base */
-            p->arch.user_regs.fs_base = 0;
+        all_segs_okay &= loadsegment(fs, nctxt->user_regs.fs);
+        if ( pctxt->user_regs.fs ) /* != 0 selector kills fs_base */
+            pctxt->fs_base = 0;
     }
 
     /*
      * Either selector != 0 ==> reload.
      * Also reload to reset GS_BASE if it was non-zero.
      */
-    if ( unlikely(p->arch.user_regs.gs |
-                  p->arch.user_regs.gs_base_user |
-                  n->arch.user_regs.gs) )
+    if ( unlikely(pctxt->user_regs.gs |
+                  pctxt->gs_base_user |
+                  nctxt->user_regs.gs) )
     {
         /* Reset GS_BASE with user %gs? */
-        if ( p->arch.user_regs.gs || !n->arch.user_regs.gs_base_user )
-            all_segs_okay &= loadsegment(gs, n->arch.user_regs.gs);
-        if ( p->arch.user_regs.gs ) /* != 0 selector kills gs_base_user */
-            p->arch.user_regs.gs_base_user = 0;
+        if ( pctxt->user_regs.gs || !nctxt->gs_base_user )
+            all_segs_okay &= loadsegment(gs, nctxt->user_regs.gs);
+        if ( pctxt->user_regs.gs ) /* != 0 selector kills gs_base_user */
+            pctxt->gs_base_user = 0;
     }
 
     /* This can only be non-zero if selector is NULL. */
-    if ( n->arch.user_regs.fs_base )
+    if ( nctxt->fs_base )
         wrmsr(MSR_FS_BASE,
-              n->arch.user_regs.fs_base,
-              n->arch.user_regs.fs_base>>32);
+              nctxt->fs_base,
+              nctxt->fs_base>>32);
 
     /* Most kernels have non-zero GS base, so don't bother testing. */
     /* (This is also a serialising instruction, avoiding AMD erratum #88.) */
     wrmsr(MSR_SHADOW_GS_BASE,
-          n->arch.user_regs.gs_base_kernel,
-          n->arch.user_regs.gs_base_kernel>>32);
+          nctxt->gs_base_kernel,
+          nctxt->gs_base_kernel>>32);
 
     /* This can only be non-zero if selector is NULL. */
-    if ( n->arch.user_regs.gs_base_user )
+    if ( nctxt->gs_base_user )
         wrmsr(MSR_GS_BASE,
-              n->arch.user_regs.gs_base_user,
-              n->arch.user_regs.gs_base_user>>32);
+              nctxt->gs_base_user,
+              nctxt->gs_base_user>>32);
 
     /* If in kernel mode then switch the GS bases around. */
     if ( n->arch.flags & TF_kernel_mode )
@@ -625,24 +602,24 @@ static void load_segments(struct exec_domain *p, struct exec_domain *n)
         unsigned long   *rsp =
             (n->arch.flags & TF_kernel_mode) ?
             (unsigned long *)regs->rsp : 
-            (unsigned long *)n->arch.kernel_sp;
+            (unsigned long *)nctxt->kernel_sp;
 
         if ( !(n->arch.flags & TF_kernel_mode) )
             toggle_guest_mode(n);
         else
             regs->cs &= ~3;
 
-        if ( put_user(regs->ss,             rsp- 1) |
-             put_user(regs->rsp,            rsp- 2) |
-             put_user(regs->rflags,         rsp- 3) |
-             put_user(regs->cs,             rsp- 4) |
-             put_user(regs->rip,            rsp- 5) |
-             put_user(n->arch.user_regs.gs, rsp- 6) |
-             put_user(n->arch.user_regs.fs, rsp- 7) |
-             put_user(n->arch.user_regs.es, rsp- 8) |
-             put_user(n->arch.user_regs.ds, rsp- 9) |
-             put_user(regs->r11,            rsp-10) |
-             put_user(regs->rcx,            rsp-11) )
+        if ( put_user(regs->ss,            rsp- 1) |
+             put_user(regs->rsp,           rsp- 2) |
+             put_user(regs->rflags,        rsp- 3) |
+             put_user(regs->cs,            rsp- 4) |
+             put_user(regs->rip,           rsp- 5) |
+             put_user(nctxt->user_regs.gs, rsp- 6) |
+             put_user(nctxt->user_regs.fs, rsp- 7) |
+             put_user(nctxt->user_regs.es, rsp- 8) |
+             put_user(nctxt->user_regs.ds, rsp- 9) |
+             put_user(regs->r11,           rsp-10) |
+             put_user(regs->rcx,           rsp-11) )
         {
             DPRINTK("Error while creating failsafe callback frame.\n");
             domain_crash();
@@ -653,16 +630,17 @@ static void load_segments(struct exec_domain *p, struct exec_domain *n)
         regs->ss            = __GUEST_SS;
         regs->rsp           = (unsigned long)(rsp-11);
         regs->cs            = __GUEST_CS;
-        regs->rip           = n->arch.failsafe_address;
+        regs->rip           = nctxt->failsafe_callback_eip;
     }
 }
 
-static void save_segments(struct exec_domain *p)
+static void save_segments(struct exec_domain *ed)
 {
-    __asm__ __volatile__ ( "movl %%ds,%0" : "=m" (p->arch.user_regs.ds) );
-    __asm__ __volatile__ ( "movl %%es,%0" : "=m" (p->arch.user_regs.es) );
-    __asm__ __volatile__ ( "movl %%fs,%0" : "=m" (p->arch.user_regs.fs) );
-    __asm__ __volatile__ ( "movl %%gs,%0" : "=m" (p->arch.user_regs.gs) );
+    struct cpu_user_regs *regs = &ed->arch.guest_context.user_regs;
+    __asm__ __volatile__ ( "movl %%ds,%0" : "=m" (regs->ds) );
+    __asm__ __volatile__ ( "movl %%es,%0" : "=m" (regs->es) );
+    __asm__ __volatile__ ( "movl %%fs,%0" : "=m" (regs->fs) );
+    __asm__ __volatile__ ( "movl %%gs,%0" : "=m" (regs->gs) );
 }
 
 static void clear_segments(void)
@@ -695,7 +673,7 @@ long do_switch_to_user(void)
     regs->rsp    = stu.rsp;
     regs->ss     = stu.ss | 3; /* force guest privilege */
 
-    if ( !(stu.flags & ECF_IN_SYSCALL) )
+    if ( !(stu.flags & VGCF_IN_SYSCALL) )
     {
         regs->entry_vector = 0;
         regs->r11 = stu.r11;
@@ -717,8 +695,8 @@ long do_switch_to_user(void)
 static inline void switch_kernel_stack(struct exec_domain *n, unsigned int cpu)
 {
     struct tss_struct *tss = &init_tss[cpu];
-    tss->esp1 = n->arch.kernel_sp;
-    tss->ss1  = n->arch.kernel_ss;
+    tss->esp1 = n->arch.guest_context.kernel_sp;
+    tss->ss1  = n->arch.guest_context.kernel_ss;
 }
 
 #endif
@@ -728,15 +706,15 @@ static inline void switch_kernel_stack(struct exec_domain *n, unsigned int cpu)
 
 static void __context_switch(void)
 {
-    struct cpu_user_regs *stack_ec = get_cpu_user_regs();
+    struct cpu_user_regs *stack_regs = get_cpu_user_regs();
     unsigned int         cpu = smp_processor_id();
     struct exec_domain  *p = percpu_ctxt[cpu].curr_ed;
     struct exec_domain  *n = current;
 
     if ( !is_idle_task(p->domain) )
     {
-        memcpy(&p->arch.user_regs,
-               stack_ec
+        memcpy(&p->arch.guest_context.user_regs,
+               stack_regs
                CTXT_SWITCH_STACK_BYTES);
         unlazy_fpu(p);
         CLEAR_FAST_TRAP(&p->arch);
@@ -745,20 +723,20 @@ static void __context_switch(void)
 
     if ( !is_idle_task(n->domain) )
     {
-        memcpy(stack_ec,
-               &n->arch.user_regs,
+        memcpy(stack_regs,
+               &n->arch.guest_context.user_regs,
                CTXT_SWITCH_STACK_BYTES);
 
         /* Maybe switch the debug registers. */
-        if ( unlikely(n->arch.debugreg[7]) )
+        if ( unlikely(n->arch.guest_context.debugreg[7]) )
         {
-            loaddebug(&n->arch, 0);
-            loaddebug(&n->arch, 1);
-            loaddebug(&n->arch, 2);
-            loaddebug(&n->arch, 3);
+            loaddebug(&n->arch.guest_context, 0);
+            loaddebug(&n->arch.guest_context, 1);
+            loaddebug(&n->arch.guest_context, 2);
+            loaddebug(&n->arch.guest_context, 3);
             /* no 4 and 5 */
-            loaddebug(&n->arch, 6);
-            loaddebug(&n->arch, 7);
+            loaddebug(&n->arch.guest_context, 6);
+            loaddebug(&n->arch.guest_context, 7);
         }
 
         if ( !VMX_DOMAIN(n) )
index f1488d6f081fa7638fe1e8c9fb92d76900122639..5a82ac60eb56878f7f08f9e06b00398087a5ca94 100644 (file)
@@ -222,14 +222,15 @@ int construct_dom0(struct domain *d,
      * We're basically forcing default RPLs to 1, so that our "what privilege
      * level are we returning to?" logic works.
      */
-    ed->arch.failsafe_selector = FLAT_KERNEL_CS;
-    ed->arch.event_selector    = FLAT_KERNEL_CS;
-    ed->arch.kernel_ss = FLAT_KERNEL_SS;
+    ed->arch.guest_context.kernel_ss = FLAT_KERNEL_SS;
     for ( i = 0; i < 256; i++ ) 
-        ed->arch.traps[i].cs = FLAT_KERNEL_CS;
+        ed->arch.guest_context.trap_ctxt[i].cs = FLAT_KERNEL_CS;
 
 #if defined(__i386__)
 
+    ed->arch.guest_context.failsafe_callback_cs = FLAT_KERNEL_CS;
+    ed->arch.guest_context.event_callback_cs    = FLAT_KERNEL_CS;
+
     /*
      * Protect the lowest 1GB of memory. We use a temporary mapping there
      * from which we copy the kernel and ramdisk images.
index 82cf45bbaca437d02ed16646af7068b836c952f7..f25973398fa1c5ce366e171b9ca7bf6b568c8dfa 100644 (file)
@@ -34,11 +34,11 @@ void save_init_fpu(struct exec_domain *tsk)
     if ( cpu_has_fxsr )
         __asm__ __volatile__ (
             "fxsave %0 ; fnclex"
-            : "=m" (tsk->arch.i387) );
+            : "=m" (tsk->arch.guest_context.fpu_ctxt) );
     else
         __asm__ __volatile__ (
             "fnsave %0 ; fwait"
-            : "=m" (tsk->arch.i387) );
+            : "=m" (tsk->arch.guest_context.fpu_ctxt) );
 
     clear_bit(EDF_USEDFPU, &tsk->ed_flags);
     stts();
@@ -49,11 +49,11 @@ void restore_fpu(struct exec_domain *tsk)
     if ( cpu_has_fxsr )
         __asm__ __volatile__ (
             "fxrstor %0"
-            : : "m" (tsk->arch.i387) );
+            : : "m" (tsk->arch.guest_context.fpu_ctxt) );
     else
         __asm__ __volatile__ (
             "frstor %0"
-            : : "m" (tsk->arch.i387) );
+            : : "m" (tsk->arch.guest_context.fpu_ctxt) );
 }
 
 /*
index 0c7e9da529ca2aa6e3ff03b432e4f57bf8dc4d33..43d2d2daea57c56cca28ecbb1295973919d55186 100644 (file)
@@ -285,7 +285,7 @@ int map_ldt_shadow_page(unsigned int off)
     struct domain *d = ed->domain;
     unsigned long gpfn, gmfn;
     l1_pgentry_t l1e, nl1e;
-    unsigned gva = ed->arch.ldt_base + (off << PAGE_SHIFT);
+    unsigned gva = ed->arch.guest_context.ldt_base + (off << PAGE_SHIFT);
     int res;
 
 #if defined(__x86_64__)
@@ -1639,12 +1639,12 @@ int do_mmuext_op(
                 okay = 0;
                 MEM_LOG("Bad args to SET_LDT: ptr=%lx, ents=%lx", ptr, ents);
             }
-            else if ( (ed->arch.ldt_ents != ents) || 
-                      (ed->arch.ldt_base != ptr) )
+            else if ( (ed->arch.guest_context.ldt_ents != ents) || 
+                      (ed->arch.guest_context.ldt_base != ptr) )
             {
                 invalidate_shadow_ldt(ed);
-                ed->arch.ldt_base = ptr;
-                ed->arch.ldt_ents = ents;
+                ed->arch.guest_context.ldt_base = ptr;
+                ed->arch.guest_context.ldt_ents = ents;
                 load_LDT(ed);
                 percpu_info[cpu].deferred_ops &= ~DOP_RELOAD_LDT;
                 if ( ents != 0 )
index 9d69d69492177548e1897dcf16bf2955cffc360b..3c5cc07c0caf51282a1ad70fbf0d6791146b392e 100644 (file)
@@ -150,11 +150,12 @@ static inline int do_trap(int trapnr, char *str,
         goto xen_fault;
 
 #ifndef NDEBUG
-    if ( (ed->arch.traps[trapnr].address == 0) && (ed->domain->id == 0) )
+    if ( (ed->arch.guest_context.trap_ctxt[trapnr].address == 0) &&
+         (ed->domain->id == 0) )
         goto xen_fault;
 #endif
 
-    ti = current->arch.traps + trapnr;
+    ti = &current->arch.guest_context.trap_ctxt[trapnr];
     tb->flags = TBF_EXCEPTION;
     tb->cs    = ti->cs;
     tb->eip   = ti->address;
@@ -224,7 +225,7 @@ asmlinkage int do_int3(struct cpu_user_regs *regs)
         panic("CPU%d FATAL TRAP: vector = 3 (Int3)\n", smp_processor_id());
     } 
 
-    ti = current->arch.traps + 3;
+    ti = &current->arch.guest_context.trap_ctxt[TRAP_int3];
     tb->flags = TBF_EXCEPTION;
     tb->cs    = ti->cs;
     tb->eip   = ti->address;
@@ -245,7 +246,7 @@ void propagate_page_fault(unsigned long addr, u16 error_code)
     struct exec_domain *ed = current;
     struct trap_bounce *tb = &ed->arch.trap_bounce;
 
-    ti = ed->arch.traps + 14;
+    ti = &ed->arch.guest_context.trap_ctxt[TRAP_page_fault];
     tb->flags = TBF_EXCEPTION | TBF_EXCEPTION_ERRCODE | TBF_EXCEPTION_CR2;
     tb->cr2        = addr;
     tb->error_code = error_code;
@@ -303,7 +304,8 @@ asmlinkage int do_page_fault(struct cpu_user_regs *regs)
     }
 
     if ( unlikely(addr >= LDT_VIRT_START(ed)) && 
-         (addr < (LDT_VIRT_START(ed) + (ed->arch.ldt_ents*LDT_ENTRY_SIZE))) )
+         (addr < (LDT_VIRT_START(ed) + 
+                  (ed->arch.guest_context.ldt_ents*LDT_ENTRY_SIZE))) )
     {
         /*
          * Copy a mapping from the guest's LDT, if it is valid. Otherwise we
@@ -312,7 +314,7 @@ asmlinkage int do_page_fault(struct cpu_user_regs *regs)
         extern int map_ldt_shadow_page(unsigned int);
         LOCK_BIGLOCK(d);
         off  = addr - LDT_VIRT_START(ed);
-        addr = ed->arch.ldt_base + off;
+        addr = ed->arch.guest_context.ldt_base + off;
         ret = map_ldt_shadow_page(off >> PAGE_SHIFT);
         UNLOCK_BIGLOCK(d);
         if ( likely(ret) )
@@ -323,7 +325,8 @@ asmlinkage int do_page_fault(struct cpu_user_regs *regs)
         goto xen_fault;
 
 #ifndef NDEBUG
-    if ( (ed->arch.traps[TRAP_page_fault].address == 0) && (d->id == 0) )
+    if ( (ed->arch.guest_context.trap_ctxt[TRAP_page_fault].address == 0) &&
+         (d->id == 0) )
         goto xen_fault;
 #endif
 
@@ -781,7 +784,7 @@ asmlinkage int do_general_protection(struct cpu_user_regs *regs)
     if ( (regs->error_code & 3) == 2 )
     {
         /* This fault must be due to <INT n> instruction. */
-        ti = current->arch.traps + (regs->error_code>>3);
+        ti = &current->arch.guest_context.trap_ctxt[regs->error_code>>3];
         if ( PERMIT_SOFTINT(TI_GET_DPL(ti), ed, regs) )
         {
             tb->flags = TBF_EXCEPTION;
@@ -803,13 +806,13 @@ asmlinkage int do_general_protection(struct cpu_user_regs *regs)
 #endif
 
 #ifndef NDEBUG
-    if ( (ed->arch.traps[TRAP_gp_fault].address == 0) &&
+    if ( (ed->arch.guest_context.trap_ctxt[TRAP_gp_fault].address == 0) &&
          (ed->domain->id == 0) )
         goto gp_in_kernel;
 #endif
 
     /* Pass on GPF as is. */
-    ti = current->arch.traps + 13;
+    ti = &current->arch.guest_context.trap_ctxt[TRAP_gp_fault];
     tb->flags      = TBF_EXCEPTION | TBF_EXCEPTION_ERRCODE;
     tb->error_code = regs->error_code;
  finish_propagation:
@@ -916,21 +919,20 @@ asmlinkage int math_state_restore(struct cpu_user_regs *regs)
     /* Prevent recursion. */
     clts();
 
-    if ( !test_bit(EDF_USEDFPU, &current->ed_flags) )
+    if ( !test_and_set_bit(EDF_USEDFPU, &current->ed_flags) )
     {
         if ( test_bit(EDF_DONEFPUINIT, &current->ed_flags) )
             restore_fpu(current);
         else
             init_fpu();
-        set_bit(EDF_USEDFPU, &current->ed_flags); /* so we fnsave on switch_to() */
     }
 
     if ( test_and_clear_bit(EDF_GUEST_STTS, &current->ed_flags) )
     {
         struct trap_bounce *tb = &current->arch.trap_bounce;
-        tb->flags      = TBF_EXCEPTION;
-        tb->cs         = current->arch.traps[7].cs;
-        tb->eip        = current->arch.traps[7].address;
+        tb->flags = TBF_EXCEPTION;
+        tb->cs    = current->arch.guest_context.trap_ctxt[7].cs;
+        tb->eip   = current->arch.guest_context.trap_ctxt[7].address;
     }
 
     return EXCRET_fault_fixed;
@@ -946,7 +948,7 @@ asmlinkage int do_debug(struct cpu_user_regs *regs)
 
     /* Mask out spurious debug traps due to lazy DR7 setting */
     if ( (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) &&
-         (ed->arch.debugreg[7] == 0) )
+         (ed->arch.guest_context.debugreg[7] == 0) )
     {
         __asm__("mov %0,%%db7" : : "r" (0UL));
         goto out;
@@ -968,11 +970,11 @@ asmlinkage int do_debug(struct cpu_user_regs *regs)
     } 
 
     /* Save debug status register where guest OS can peek at it */
-    ed->arch.debugreg[6] = condition;
+    ed->arch.guest_context.debugreg[6] = condition;
 
     tb->flags = TBF_EXCEPTION;
-    tb->cs    = ed->arch.traps[1].cs;
-    tb->eip   = ed->arch.traps[1].address;
+    tb->cs    = ed->arch.guest_context.trap_ctxt[TRAP_debug].cs;
+    tb->eip   = ed->arch.guest_context.trap_ctxt[TRAP_debug].address;
 
  out:
     return EXCRET_not_a_fault;
@@ -1059,7 +1061,7 @@ void __init trap_init(void)
 long do_set_trap_table(trap_info_t *traps)
 {
     trap_info_t cur;
-    trap_info_t *dst = current->arch.traps;
+    trap_info_t *dst = current->arch.guest_context.trap_ctxt;
     long rc = 0;
 
     LOCK_BIGLOCK(current->domain);
@@ -1163,7 +1165,7 @@ long set_debugreg(struct exec_domain *p, int reg, unsigned long value)
         return -EINVAL;
     }
 
-    p->arch.debugreg[reg] = value;
+    p->arch.guest_context.debugreg[reg] = value;
     return 0;
 }
 
@@ -1175,7 +1177,7 @@ long do_set_debugreg(int reg, unsigned long value)
 unsigned long do_get_debugreg(int reg)
 {
     if ( (reg < 0) || (reg > 7) ) return -EINVAL;
-    return current->arch.debugreg[reg];
+    return current->arch.guest_context.debugreg[reg];
 }
 
 /*
index b67612c3d95a2ece3b6c02927b3b43288f7a372e..24a9bc7089a042b7ddba92a2b29698218b734223 100644 (file)
@@ -250,18 +250,18 @@ static void vmx_dr_access (unsigned long exit_qualification, struct cpu_user_reg
     case TYPE_MOV_TO_DR: 
         /* don't need to check the range */
         if (reg != REG_ESP)
-            ed->arch.debugreg[reg] = *reg_p; 
+            ed->arch.guest_context.debugreg[reg] = *reg_p; 
         else {
             unsigned long value;
             __vmread(GUEST_ESP, &value);
-            ed->arch.debugreg[reg] = value;
+            ed->arch.guest_context.debugreg[reg] = value;
         }
         break;
     case TYPE_MOV_FROM_DR:
         if (reg != REG_ESP)
-            *reg_p = ed->arch.debugreg[reg];
+            *reg_p = ed->arch.guest_context.debugreg[reg];
         else {
-            __vmwrite(GUEST_ESP, ed->arch.debugreg[reg]);
+            __vmwrite(GUEST_ESP, ed->arch.guest_context.debugreg[reg]);
         }
         break;
     }
index 8e9ad32f6a815fde142e0a6527288fd392b1ea75..7015b2a861649df48b94b069733fb302aabc1278 100644 (file)
@@ -48,14 +48,20 @@ void __dummy__(void)
 
     OFFSET(EDOMAIN_processor, struct exec_domain, processor);
     OFFSET(EDOMAIN_vcpu_info, struct exec_domain, vcpu_info);
-    OFFSET(EDOMAIN_event_sel, struct exec_domain, arch.event_selector);
-    OFFSET(EDOMAIN_event_addr, struct exec_domain, arch.event_address);
-    OFFSET(EDOMAIN_failsafe_sel, struct exec_domain, arch.failsafe_selector);
-    OFFSET(EDOMAIN_failsafe_addr, struct exec_domain, arch.failsafe_address);
     OFFSET(EDOMAIN_trap_bounce, struct exec_domain, arch.trap_bounce);
     OFFSET(EDOMAIN_thread_flags, struct exec_domain, arch.flags);
-    OFFSET(EDOMAIN_kernel_ss, struct exec_domain, arch.kernel_ss);
-    OFFSET(EDOMAIN_kernel_sp, struct exec_domain, arch.kernel_sp);
+    OFFSET(EDOMAIN_event_sel, struct exec_domain,
+           arch.guest_context.event_callback_cs);
+    OFFSET(EDOMAIN_event_addr, struct exec_domain, 
+           arch.guest_context.event_callback_eip);
+    OFFSET(EDOMAIN_failsafe_sel, struct exec_domain,
+           arch.guest_context.failsafe_callback_cs);
+    OFFSET(EDOMAIN_failsafe_addr, struct exec_domain,
+           arch.guest_context.failsafe_callback_eip);
+    OFFSET(EDOMAIN_kernel_ss, struct exec_domain,
+           arch.guest_context.kernel_ss);
+    OFFSET(EDOMAIN_kernel_sp, struct exec_domain,
+           arch.guest_context.kernel_sp);
     BLANK();
 
     OFFSET(VCPUINFO_upcall_pending, vcpu_info_t, evtchn_upcall_pending);
index 75199bb57863441bc87a5eba9a7b172d18ac35b8..045d904c218f7ba07685febe59ac9c9450c07839 100644 (file)
@@ -188,8 +188,8 @@ long do_stack_switch(unsigned long ss, unsigned long esp)
     if ( (ss & 3) != 1 )
         return -EPERM;
 
-    current->arch.kernel_ss = ss;
-    current->arch.kernel_sp = esp;
+    current->arch.guest_context.kernel_ss = ss;
+    current->arch.guest_context.kernel_sp = esp;
     t->ss1  = ss;
     t->esp1 = esp;
 
index 4f448b7ae1a45d27882b08c564f01fe5c0244b19..0a3a17e455bec6faf908b5359a2d79137c4804bb 100644 (file)
@@ -115,7 +115,7 @@ int get_baselimit(u16 seg, unsigned long *base, unsigned long *limit)
     if ( ldt )
     {
         table = (unsigned long *)LDT_VIRT_START(d);
-        if ( idx >= d->arch.ldt_ents )
+        if ( idx >= d->arch.guest_context.ldt_ents )
             goto fail;
     }
     else /* gdt */
@@ -181,7 +181,7 @@ int fixup_seg(u16 seg, unsigned long offset)
     if ( ldt )
     {
         table = (unsigned long *)LDT_VIRT_START(d);
-        if ( idx >= d->arch.ldt_ents )
+        if ( idx >= d->arch.guest_context.ldt_ents )
         {
             DPRINTK("Segment %04x out of LDT range (%ld)\n",
                     seg, d->arch.ldt_ents);
@@ -449,7 +449,7 @@ int gpf_emulate_4gb(struct cpu_user_regs *regs)
     /* If requested, give a callback on otherwise unused vector 15. */
     if ( VM_ASSIST(d->domain, VMASST_TYPE_4gb_segments_notify) )
     {
-        ti  = &d->arch.traps[15];
+        ti  = &d->arch.guest_context.trap_ctxt[15];
         tb  = &d->arch.trap_bounce;
         tb->flags      = TBF_EXCEPTION | TBF_EXCEPTION_ERRCODE;
         tb->error_code = pb - eip;
index a5be49896d533b8ba4fe9c6c54bc3eed3015a0af..bd14acde01fa7bdc552f20520222e4b99577e705 100644 (file)
@@ -281,7 +281,7 @@ long set_fast_trap(struct exec_domain *p, int idx)
     if ( (idx != 0x80) && ((idx < 0x20) || (idx > 0x2f)) ) 
         return -1;
 
-    ti = p->arch.traps + idx;
+    ti = &p->arch.guest_context.trap_ctxt[idx];
 
     /*
      * We can't virtualise interrupt gates, as there's no way to get
@@ -293,7 +293,7 @@ long set_fast_trap(struct exec_domain *p, int idx)
     if ( p == current )
         CLEAR_FAST_TRAP(&p->arch);
 
-    p->arch.fast_trap_idx    = idx;
+    p->arch.guest_context.fast_trap_idx = idx;
     p->arch.fast_trap_desc.a = (ti->cs << 16) | (ti->address & 0xffff);
     p->arch.fast_trap_desc.b = 
         (ti->address & 0xffff0000) | 0x8f00 | (TI_GET_DPL(ti)&3)<<13;
@@ -320,10 +320,10 @@ long do_set_callbacks(unsigned long event_selector,
     if ( !VALID_CODESEL(event_selector) || !VALID_CODESEL(failsafe_selector) )
         return -EPERM;
 
-    d->arch.event_selector    = event_selector;
-    d->arch.event_address     = event_address;
-    d->arch.failsafe_selector = failsafe_selector;
-    d->arch.failsafe_address  = failsafe_address;
+    d->arch.guest_context.event_callback_cs     = event_selector;
+    d->arch.guest_context.event_callback_eip    = event_address;
+    d->arch.guest_context.failsafe_callback_cs  = failsafe_selector;
+    d->arch.guest_context.failsafe_callback_eip = failsafe_address;
 
     return 0;
 }
index 3f06bc79c495ce106f170846ac0b48761c0644b9..c6f3598b25943fba111ed316bade6e6cafd1dc72 100644 (file)
@@ -52,12 +52,16 @@ void __dummy__(void)
 
     OFFSET(EDOMAIN_processor, struct exec_domain, processor);
     OFFSET(EDOMAIN_vcpu_info, struct exec_domain, vcpu_info);
-    OFFSET(EDOMAIN_event_addr, struct exec_domain, arch.event_address);
-    OFFSET(EDOMAIN_failsafe_addr, struct exec_domain, arch.failsafe_address);
-    OFFSET(EDOMAIN_syscall_addr, struct exec_domain, arch.syscall_address);
     OFFSET(EDOMAIN_trap_bounce, struct exec_domain, arch.trap_bounce);
     OFFSET(EDOMAIN_thread_flags, struct exec_domain, arch.flags);
-    OFFSET(EDOMAIN_kernel_sp, struct exec_domain, arch.kernel_sp);
+    OFFSET(EDOMAIN_event_addr, struct exec_domain,
+           arch.guest_context.event_callback_eip);
+    OFFSET(EDOMAIN_failsafe_addr, struct exec_domain,
+           arch.guest_context.failsafe_callback_eip);
+    OFFSET(EDOMAIN_syscall_addr, struct exec_domain,
+           arch.guest_context.syscall_callback_eip);
+    OFFSET(EDOMAIN_kernel_sp, struct exec_domain,
+           arch.guest_context.kernel_sp);
     BLANK();
 
     OFFSET(VCPUINFO_upcall_pending, vcpu_info_t, evtchn_upcall_pending);
index 518b1c530192757a9e6d9fa148756842679c2ea7..b4280a1ff56e399aa96ca618b08759977d869c31 100644 (file)
@@ -161,9 +161,6 @@ test_all_events:
  *
  * We also need the room, especially because orig_eax field is used 
  * by do_IRQ(). Compared the cpu_user_regs, we skip pushing for the following:
- *   (13) u64 gs_base_user;                 
- *   (12) u64 gs_base_kernel;                 
- *   (11) u64 fs_base;                 
  *   (10) u64 gs;                 
  *   (9)  u64 fs;
  *   (8)  u64 ds;
@@ -176,9 +173,6 @@ test_all_events:
  *   (2)  u64 rip;
  * (2/1)  u32 entry_vector;
  * (1/1)  u32 error_code;
- * However, get_stack_bottom() actually returns 64 bytes before the real
- * bottom of the stack to allow space for:
- * domain pointer, DS, ES, FS, GS. Therefore, we effectively skip 6 registers.
  */
 #define VMX_MONITOR_RFLAGS     0x202 /* IF on */
 #define NR_SKIPPED_REGS        6       /* See the above explanation */
index 90b81bca025014e8ba77bdbf3b898a4b9c36d28b..a1db5acd05d8ccd5fbc0483b9c88c11313a3961a 100644 (file)
@@ -240,8 +240,8 @@ long do_stack_switch(unsigned long ss, unsigned long esp)
 {
     if ( (ss & 3) != 3 )
         return -EPERM;
-    current->arch.kernel_ss = ss;
-    current->arch.kernel_sp = esp;
+    current->arch.guest_context.kernel_ss = ss;
+    current->arch.guest_context.kernel_sp = esp;
     return 0;
 }
 
@@ -253,21 +253,24 @@ long do_set_segment_base(unsigned int which, unsigned long base)
     switch ( which )
     {
     case SEGBASE_FS:
-        ed->arch.user_regs.fs_base = base;
         if ( wrmsr_user(MSR_FS_BASE, base, base>>32) )
             ret = -EFAULT;
+        else
+            ed->arch.guest_context.fs_base = base;
         break;
 
     case SEGBASE_GS_USER:
-        ed->arch.user_regs.gs_base_user = base;
         if ( wrmsr_user(MSR_SHADOW_GS_BASE, base, base>>32) )
             ret = -EFAULT;
+        else
+            ed->arch.guest_context.gs_base_user = base;
         break;
 
     case SEGBASE_GS_KERNEL:
-        ed->arch.user_regs.gs_base_kernel = base;
         if ( wrmsr_user(MSR_GS_BASE, base, base>>32) )
             ret = -EFAULT;
+        else
+            ed->arch.guest_context.gs_base_kernel = base;
         break;
 
     case SEGBASE_GS_USER_SEL:
index a81eea145a7b682a82d44907322a1899e915731b..33475b3af0ddcd95ca0bc8ecbc8fcdbf75f3c1ce 100644 (file)
@@ -255,9 +255,9 @@ long do_set_callbacks(unsigned long event_address,
 {
     struct exec_domain *d = current;
 
-    d->arch.event_address    = event_address;
-    d->arch.failsafe_address = failsafe_address;
-    d->arch.syscall_address  = syscall_address;
+    d->arch.guest_context.event_callback_eip    = event_address;
+    d->arch.guest_context.failsafe_callback_eip = failsafe_address;
+    d->arch.guest_context.syscall_callback_eip  = syscall_address;
 
     return 0;
 }
index 5f875d6e2fc17007e51a5e0cf359cb2b08c1f723..514ccdf0f10fbd4477362fa7dc9a3e10148351af 100644 (file)
@@ -66,38 +66,12 @@ struct arch_domain
 
 struct arch_exec_domain
 {
-    unsigned long      kernel_sp;
-    unsigned long      kernel_ss;
+    struct vcpu_guest_context guest_context;
 
     unsigned long      flags; /* TF_ */
 
-    /* Hardware debugging registers */
-    unsigned long      debugreg[8];  /* %%db0-7 debug registers */
-
-    /* floating point info */
-    struct i387_state  i387;
-
-    /* general user-visible register state */
-    struct cpu_user_regs user_regs;
-
     void (*schedule_tail) (struct exec_domain *);
 
-    /*
-     * Return vectors pushed to us by guest OS.
-     * The stack frame for events is exactly that of an x86 hardware interrupt.
-     * The stack frame for a failsafe callback is augmented with saved values
-     * for segment registers %ds, %es, %fs and %gs:
-     *  %ds, %es, %fs, %gs, %eip, %cs, %eflags [, %oldesp, %oldss]
-     */
-
-    unsigned long event_selector;    /* entry CS  (x86/32 only) */
-    unsigned long event_address;     /* entry EIP */
-
-    unsigned long failsafe_selector; /* entry CS  (x86/32 only) */
-    unsigned long failsafe_address;  /* entry EIP */
-
-    unsigned long syscall_address;   /* entry EIP (x86/64 only) */
-
     /* Bounce information for propagating an exception to guest OS. */
     struct trap_bounce trap_bounce;
 
@@ -108,10 +82,8 @@ struct arch_exec_domain
 
     /* Trap info. */
 #ifdef ARCH_HAS_FAST_TRAP
-    int                fast_trap_idx;
     struct desc_struct fast_trap_desc;
 #endif
-    trap_info_t        traps[256];
 
     /* Virtual Machine Extensions */
     struct arch_vmx_struct arch_vmx;
@@ -143,7 +115,7 @@ struct arch_exec_domain
     unsigned long guest_cr2;
 
     /* Current LDT details. */
-    unsigned long ldt_base, ldt_ents, shadow_ldt_mapcnt;
+    unsigned long shadow_ldt_mapcnt;
     /* Next entry is passed to LGDT on domain switch. */
     char gdt[10]; /* NB. 10 bytes needed for x86_64. Use 6 bytes for x86_32. */
 } __cacheline_aligned;
index 096f7286d067d3077cb1814e1b306a782a8de745..63fa8db5d847a88d286fdac09f2135bdec95a5e7 100644 (file)
@@ -10,7 +10,7 @@ static inline void load_LDT(struct exec_domain *ed)
     struct desc_struct *desc;
     unsigned long ents;
 
-    if ( (ents = ed->arch.ldt_ents) == 0 )
+    if ( (ents = ed->arch.guest_context.ldt_ents) == 0 )
     {
         __asm__ __volatile__ ( "lldt %%ax" : : "a" (0) );
     }
index ad8aab082b55d8994a2d7e6478131a6eb7801c64..d31b9769b93a4e5c5be1d3c7cfd3b61564415154 100644 (file)
 #define TRAP_deferred_nmi     31
 
 /* Set for entry via SYSCALL. Informs return code to use SYSRETQ not IRETQ. */
-/* NB. Same as ECF_IN_SYSCALL. No bits in common with any other TRAP_* defn. */
+/* NB. Same as VGCF_IN_SYSCALL. No bits in common with any other TRAP_ defn. */
 #define TRAP_syscall         256
 
 /*
@@ -332,10 +332,6 @@ static inline void clear_in_cr4 (unsigned long mask)
 #define IOBMP_BYTES             8192
 #define IOBMP_INVALID_OFFSET    0x8000
 
-struct i387_state {
-    u8 state[512]; /* big enough for FXSAVE */
-} __attribute__ ((aligned (16)));
-
 struct tss_struct {
     unsigned short     back_link,__blh;
 #ifdef __x86_64__
@@ -384,16 +380,18 @@ extern struct tss_struct init_tss[NR_CPUS];
 #ifdef ARCH_HAS_FAST_TRAP
 
 #define SET_DEFAULT_FAST_TRAP(_p) \
-    (_p)->fast_trap_idx = 0x20;   \
+    (_p)->guest_context.fast_trap_idx = 0x20;   \
     (_p)->fast_trap_desc.a = 0;   \
     (_p)->fast_trap_desc.b = 0;
 
 #define CLEAR_FAST_TRAP(_p) \
-    (memset(idt_tables[smp_processor_id()] + (_p)->fast_trap_idx, \
-     0, 8))
+    (memset(idt_tables[smp_processor_id()] + \
+            (_p)->guest_context.fast_trap_idx, \
+            0, 8))
 
 #define SET_FAST_TRAP(_p)   \
-    (memcpy(idt_tables[smp_processor_id()] + (_p)->fast_trap_idx, \
+    (memcpy(idt_tables[smp_processor_id()] + \
+            (_p)->guest_context.fast_trap_idx, \
             &((_p)->fast_trap_desc), 8))
 
 long set_fast_trap(struct exec_domain *p, int idx);
index 69104714660ce7ca57be50b0c3050366f0c5d926..bb6a3974220bba817709e46d6c40b574ee51e282 100644 (file)
@@ -34,15 +34,15 @@ static inline struct cpu_user_regs *get_cpu_user_regs(void)
 
 /*
  * Get the bottom-of-stack, as stored in the per-CPU TSS. This is actually
- * 64 bytes before the real bottom of the stack to allow space for:
- *  domain pointer, DS, ES, FS, GS, FS_BASE, GS_BASE_OS, GS_BASE_APP
+ * 40 bytes before the real bottom of the stack to allow space for:
+ *  domain pointer, DS, ES, FS, GS
  */
 static inline unsigned long get_stack_bottom(void)
 {
     unsigned long p;
     __asm__( "andq %%rsp,%0; addq %2,%0"
            : "=r" (p)
-           : "0" (~(STACK_SIZE-1)), "i" (STACK_SIZE-64) );
+           : "0" (~(STACK_SIZE-1)), "i" (STACK_SIZE-40) );
     return p;
 }
 
index b5dd475a2ad3ed6fa0c604f09df66b86f31f4e3c..4dbbacea8f1a1d7a6ec1e1eacb685a7d74f5b721 100644 (file)
@@ -121,21 +121,22 @@ typedef struct cpu_user_regs {
 typedef u64 tsc_timestamp_t; /* RDTSC timestamp */
 
 /*
- * The following is all CPU context. Note that the i387_ctxt block is filled 
+ * The following is all CPU context. Note that the fpu_ctxt block is filled 
  * in by FXSAVE if the CPU has feature FXSR; otherwise FSAVE is used.
  */
 typedef struct vcpu_guest_context {
-#define ECF_I387_VALID (1<<0)
-#define ECF_VMX_GUEST  (1<<1)
-#define ECF_IN_KERNEL  (1<<2)
-    unsigned long flags;
+#define VGCF_I387_VALID (1<<0)
+#define VGCF_VMX_GUEST  (1<<1)
+#define VGCF_IN_KERNEL  (1<<2)
+    unsigned long flags;                    /* VGCF_* flags                 */
     cpu_user_regs_t user_regs;              /* User-level CPU registers     */
-    char          fpu_ctxt[256];            /* User-level FPU registers     */
+    struct { char x[512]; } fpu_ctxt        /* User-level FPU registers     */
+    __attribute__((__aligned__(16)));       /* (needs 16-byte alignment)    */
     trap_info_t   trap_ctxt[256];           /* Virtual IDT                  */
     unsigned int  fast_trap_idx;            /* "Fast trap" vector offset    */
     unsigned long ldt_base, ldt_ents;       /* LDT (linear address, # ents) */
     unsigned long gdt_frames[16], gdt_ents; /* GDT (machine frames, # ents) */
-    unsigned long kernel_ss, kernel_esp;  /* Virtual TSS (only SS1/ESP1)  */
+    unsigned long kernel_ss, kernel_sp;     /* Virtual TSS (only SS1/SP1)   */
     unsigned long pt_base;                  /* CR3 (pagetable base)         */
     unsigned long debugreg[8];              /* DB0-DB7 (debug registers)    */
     unsigned long event_callback_cs;        /* CS:EIP of event callback     */
@@ -143,15 +144,15 @@ typedef struct vcpu_guest_context {
     unsigned long failsafe_callback_cs;     /* CS:EIP of failsafe callback  */
     unsigned long failsafe_callback_eip;
     unsigned long vm_assist;                /* VMASST_TYPE_* bitmap */
-} PACKED vcpu_guest_context_t;
+} vcpu_guest_context_t;
 
 typedef struct {
     /* MFN of a table of MFNs that make up p2m table */
     u64 pfn_to_mfn_frame_list;
-} PACKED arch_shared_info_t;
+} arch_shared_info_t;
 
 typedef struct {
-} PACKED arch_vcpu_info_t;
+} arch_vcpu_info_t;
 
 #define ARCH_HAS_FAST_TRAP
 
index c20327d2690f570f35c4e5e8e9b7519142a860ec..2d68bb291b33d35d665e829e40663d48251fd52d 100644 (file)
  * int HYPERVISOR_switch_to_user(void)
  * All arguments are on the kernel stack, in the following format.
  * Never returns if successful. Current kernel context is lost.
- * If flags contains ECF_IN_SYSCALL:
+ * If flags contains VGCF_IN_SYSCALL:
  *   Restore RAX, RIP, RFLAGS, RSP. 
  *   Discard R11, RCX, CS, SS.
  * Otherwise:
  * All other registers are saved on hypercall entry and restored to user.
  */
 /* Guest exited in SYSCALL context? Return to guest with SYSRET? */
-#define ECF_IN_SYSCALL (1<<8)
+#define VGCF_IN_SYSCALL (1<<8)
 struct switch_to_user {
     /* Top of stack (%rsp at point of hypercall). */
     u64 rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
@@ -167,45 +167,47 @@ typedef struct cpu_user_regs {
     u64 ss;
     u64 es;
     u64 ds;
-    u64 fs;      /* Non-zero => takes precedence over fs_base.     */
-    u64 gs;      /* Non-zero => takes precedence over gs_base_app. */
-    u64 fs_base;
-    u64 gs_base_kernel;
-    u64 gs_base_user;
+    u64 fs;      /* Non-zero => takes precedence over fs_base.      */
+    u64 gs;      /* Non-zero => takes precedence over gs_base_user. */
 } cpu_user_regs_t;
 
 typedef u64 tsc_timestamp_t; /* RDTSC timestamp */
 
 /*
- * The following is all CPU context. Note that the i387_ctxt block is filled 
+ * The following is all CPU context. Note that the fpu_ctxt block is filled 
  * in by FXSAVE if the CPU has feature FXSR; otherwise FSAVE is used.
  */
 typedef struct vcpu_guest_context {
-#define ECF_I387_VALID (1<<0)
-#define ECF_VMX_GUEST  (1<<1)
-#define ECF_IN_KERNEL  (1<<2)
-    unsigned long flags;
+#define VGCF_I387_VALID (1<<0)
+#define VGCF_VMX_GUEST  (1<<1)
+#define VGCF_IN_KERNEL  (1<<2)
+    unsigned long flags;                    /* VGCF_* flags                 */
     cpu_user_regs_t user_regs;              /* User-level CPU registers     */
-    char          fpu_ctxt[512];            /* User-level FPU registers     */
+    struct { char x[512]; } fpu_ctxt        /* User-level FPU registers     */
+    __attribute__((__aligned__(16)));       /* (needs 16-byte alignment)    */
     trap_info_t   trap_ctxt[256];           /* Virtual IDT                  */
     unsigned long ldt_base, ldt_ents;       /* LDT (linear address, # ents) */
     unsigned long gdt_frames[16], gdt_ents; /* GDT (machine frames, # ents) */
-    unsigned long kernel_ss, kernel_esp;  /* Virtual TSS (only SS1/ESP1)  */
+    unsigned long kernel_ss, kernel_sp;     /* Virtual TSS (only SS1/SP1)   */
     unsigned long pt_base;                  /* CR3 (pagetable base)         */
     unsigned long debugreg[8];              /* DB0-DB7 (debug registers)    */
     unsigned long event_callback_eip;
     unsigned long failsafe_callback_eip;
     unsigned long syscall_callback_eip;
     unsigned long vm_assist;                /* VMASST_TYPE_* bitmap */
-} PACKED vcpu_guest_context_t;
+    /* Segment base addresses. */
+    u64           fs_base;
+    u64           gs_base_kernel;
+    u64           gs_base_user;
+} vcpu_guest_context_t;
 
 typedef struct {
     /* MFN of a table of MFNs that make up p2m table */
     u64 pfn_to_mfn_frame_list;
-} PACKED arch_shared_info_t;
+} arch_shared_info_t;
 
 typedef struct {
-} PACKED arch_vcpu_info_t;
+} arch_vcpu_info_t;
 
 #endif /* !__ASSEMBLY__ */